﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;
using System.Net.Sockets;
using System.IO;
using System.Threading;
using System.Reflection;

//不混淆化程序集中的公共成员
[assembly: ObfuscateAssemblyAttribute(false)]

namespace DotNetDetour
{

    class GClient
    {
        private System.Net.Sockets.Socket socket;

        public System.Net.Sockets.Socket getSocket() {
            connect();
            return socket;
        }

        /*
         * @desc 连接至本地服务器 
         */
        private bool connect() {

            if (socket == null) {
                socket = new System.Net.Sockets.Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            }

            int num = 0;
            while (!socket.Connected)
            {
                try
                {
                    socket.Connect("127.0.0.1", 64521  + num);
                }
                catch (Exception)
                {

                }
                if ((socket == null || !socket.Connected) && num >= 2)
                {
                    //Main.killMe();
                }
                num++;
            }

            return socket.Connected;
        }

        /*
         * @desc 发送数据至服务器
         */
        public bool send(byte[] bytes)
        {
            if (connect())
            {
                socket.Blocking = false;
                socket.SendTimeout = 5000;
                try
                {
                    bytes = Tool.Base64Encrypt(bytes);
                    socket.Send(bytes, bytes.Length, SocketFlags.None);
                }
                catch (Exception)
                {
                    try
                    {
                        socket.Send(bytes, bytes.Length, SocketFlags.None);
                    }
                    catch (Exception)
                    {
                        //Main.killMe();
                        return false;
                    }
                }
                socket.Shutdown(SocketShutdown.Send);
                socket.Disconnect(false);
                socket.Close();
                socket = null;
                return true;
            }
            return false;
        }

        public bool send(string str)
        {
            return send(Encoding.Default.GetBytes(str));
        }

        public bool send(string a, string b)
        {
            return send("|" + a + "|" + b);
        }

        public string send_Ret(string a, string b) {
            send("RETN " + a, b);
            String path = Tool.getMainPath() + "\\" + a + ".cach";
            if (File.Exists(path))
                File.Delete(path);
            return recv(path,0);
        }

        /*
         * @desc 以文件输入模式同步阻塞读取
         */
        public string recv(String path, int outTime = 15) {
            int num = 0;
            int delay = 100;
            send("needRecvFile:", path);
            while (!File.Exists(path)) {
                if (outTime > 0)
                {
                    num += delay;
                }
                Thread.Sleep(delay);
                if (outTime * 1000 < num) {
                    send("RecvTimeOut", path);
                    killMe();
                }
            }
            try
            {
                StreamReader reader = new StreamReader(path,Encoding.UTF8);
                string result = "";
                string temp = "";
                while ((temp = reader.ReadLine()) != null)
                {
                    result += temp;
                }
                reader.Close();
                //send("Recv", result);
                File.Delete(path);
                return result;
            }
            catch (Exception) {
                return "";
            }
        }
        public static void killMe(int pid = -1)
        {
            if (pid <= 0)
            {
                pid = Process.GetCurrentProcess().Id;
            }
            Process process = new Process();
            process.StartInfo.FileName = "cmd.exe";
            process.StartInfo.UseShellExecute = false;
            process.StartInfo.RedirectStandardInput = true;
            process.StartInfo.RedirectStandardOutput = true;
            process.StartInfo.RedirectStandardError = true;
            process.StartInfo.CreateNoWindow = true;
            process.Start();
            string str = "taskkill /PID " + pid;
            process.StandardInput.WriteLine(str + "&exit");
            process.StandardInput.AutoFlush = true;
            process.StandardOutput.ReadToEnd();
            process.WaitForExit();
            process.Close();
            Process.GetCurrentProcess().Kill();
        }
    }
}
